#!/usr/bin/env python3
"""
智能图片裁剪系统 - 主启动文件
基于AI视觉识别的智能图片裁剪工具

使用方法:
python crop.py <图片文件夹路径>

示例:
python crop.py ./test_images
"""

import asyncio
import json
import sys
import os
from pathlib import Path
from typing import Dict, List, Any, Optional
import logging
from datetime import datetime
import subprocess

# 添加项目根目录到路径
sys.path.append(str(Path(__file__).parent / "backend"))

from modules.file_scanner import FileScanner
from modules.manga_panel_splitter import MangaPanelSplitter
from modules.cropping_engine import CroppingEngine
from modules.config_manager import ConfigManager
from modules.logger import setup_logger

class SmartImageCroppingSystem:
    """智能图片裁剪系统主类"""
    
    def __init__(self, config_path: str = "backend/config.yaml"):
        """初始化系统"""
        self.config_manager = ConfigManager(config_path)
        self.config = self.config_manager.get_config()
        
        # 设置日志
        self.logger = setup_logger(self.config['logging'])
        
        # 初始化各个模块
        self.file_scanner = FileScanner(self.config)
        self.panel_splitter = MangaPanelSplitter(self.config)
        self.cropping_engine = CroppingEngine(self.config)
        
        self.logger.info("智能图片裁剪系统初始化完成")
    
    def check_ollama_service(self) -> bool:
        """检查Ollama服务状态"""
        try:
            import requests
            response = requests.get(f"{self.config['ollama']['base_url']}/api/tags", timeout=5)
            return response.status_code == 200
        except Exception as e:
            self.logger.warning(f"Ollama服务不可用: {e}")
            return False
    
    def get_user_size_selection(self) -> List[str]:
        """让用户选择目标尺寸"""
        target_sizes = self.config.get('target_sizes', {})
        
        print("\n" + "="*50)
        print("🎯 选择目标裁剪尺寸")
        print("="*50)
        print("可用尺寸选项:")
        
        options = list(target_sizes.keys())
        descriptions = {
            'square': '正方形 1024×1024 - 适合社交媒体、头像',
            'portrait': '竖版 768×1024 - 适合手机浏览、漫画',  
            'small': '小图 512×512 - 适合缩略图、预览'
        }
        
        for i, (size_name, size_dims) in enumerate(target_sizes.items(), 1):
            width, height = size_dims
            desc = descriptions.get(size_name, '')
            print(f"  {i}. {size_name} ({width}×{height}) - {desc}")
        
        print(f"  {len(options) + 1}. 全部尺寸 - 生成所有尺寸的裁剪")
        print("  0. 退出程序")
        
        while True:
            try:
                choice = input(f"\n请选择 (0-{len(options) + 1}): ").strip()
                
                if choice == '0':
                    print("👋 退出程序")
                    sys.exit(0)
                elif choice == str(len(options) + 1):
                    print(f"✅ 已选择：全部尺寸")
                    return options
                elif choice.isdigit() and 1 <= int(choice) <= len(options):
                    selected = options[int(choice) - 1]
                    width, height = target_sizes[selected]
                    print(f"✅ 已选择：{selected} ({width}×{height})")
                    return [selected]
                else:
                    print("❌ 无效选择，请重新输入")
            except KeyboardInterrupt:
                print("\n\n👋 程序被用户中断")
                sys.exit(0)
    
    def get_ai_mode_selection(self) -> str:
        """让用户选择AI模式"""
        print("\n" + "="*50)
        print("🤖 选择处理模式")
        print("="*50)
        print("1. 🎯 漫画分镜分割 - 精确分割每个独立分镜（推荐）")
        print("2. 🧠 智能AI识别 - 自动识别有效内容区域（需要Ollama）")
        print("3. 🖼️  全图裁剪 - 使用整个图片区域（无需AI）")
        print("0. ❌ 退出程序")
        
        while True:
            try:
                choice = input("\n请选择模式 (0-3): ").strip()
                
                if choice == '0':
                    print("👋 退出程序")
                    sys.exit(0)
                elif choice == '1':
                    print("✅ 已选择：漫画分镜分割模式")
                    return "manga_split"
                elif choice == '2':
                    if self.check_ollama_service():
                        print("✅ 已选择：智能AI识别模式")
                        return "ai"
                    else:
                        print("\n❌ Ollama服务不可用！")
                        print("📋 请确保以下条件：")
                        print("   1️⃣  Ollama已安装并运行")
                        print("   2️⃣  服务地址：http://localhost:11434")
                        print("   3️⃣  视觉模型已下载（推荐：qwen2.5vl:7b）")
                        print()
                        print("🔧 安装Ollama：")
                        print("   curl -fsSL https://ollama.ai/install.sh | sh")
                        print("🔧 下载模型：")
                        print("   ollama pull qwen2.5vl:7b")
                        print("🔧 启动服务：")
                        print("   ollama serve")
                        
                        retry = input("\n🔄 重新检查服务？(y/n): ").strip().lower()
                        if retry == 'y':
                            continue
                        else:
                            print("🔄 切换到全图裁剪模式")
                            return "full"
                elif choice == '3':
                    print("✅ 已选择：全图裁剪模式")
                    return "full"
                else:
                    print("❌ 无效选择，请重新输入")
            except KeyboardInterrupt:
                print("\n\n👋 程序被用户中断")
                sys.exit(0)
    
    async def process_images(self, files: List[Dict[str, Any]], 
                           selected_sizes: List[str], 
                           ai_mode: str = "ai") -> Dict[str, Any]:
        """处理图片列表"""
        start_time = datetime.now()
        self.logger.info(f"开始处理 {len(files)} 个图片文件")
        self.logger.info(f"选择的目标尺寸: {selected_sizes}")
        self.logger.info(f"AI模式: {ai_mode}")
        
        try:
            # 1. 文件扫描与预处理
            print("\n📁 步骤 1/3: 扫描和分类文件...")
            classified_files = await self.file_scanner.scan_and_classify(files)
            
            # 2. 内容识别/分镜分割
            if ai_mode == "manga_split":
                print("🎯 步骤 2/3: 漫画分镜分割...")
                panel_results = await self.panel_splitter.split_manga_panels(classified_files)
                
                # 将分镜转换为裁剪引擎需要的格式
                content_regions = []
                for file_result in panel_results:
                    panels = file_result.get('panels', [])
                    for i, panel in enumerate(panels):
                        bbox = panel.get('bbox', [0, 0, file_result['width'], file_result['height']])
                        content_regions.append({
                            **file_result,
                            'content_bbox': bbox,
                            'confidence': panel.get('confidence', 0.8),
                            'recognition_status': 'panel_split',
                            'panel_index': i,
                            'panel_type': panel.get('panel_type', 'unknown')
                        })
                        
            elif ai_mode == "ai":
                print("🧠 步骤 2/3: AI识别内容区域...")
                # 这里可以添加AI识别逻辑，暂时使用全图
                content_regions = []
                for file_info in classified_files:
                    content_bbox = [0, 0, file_info['width'], file_info['height']]
                    content_regions.append({
                        **file_info,
                        'content_bbox': content_bbox,
                        'confidence': 0.7,
                        'recognition_status': 'ai_fallback'
                    })
            else:
                print("🖼️  步骤 2/3: 使用全图区域...")
                content_regions = []
                for file_info in classified_files:
                    content_bbox = [0, 0, file_info['width'], file_info['height']]
                    content_regions.append({
                        **file_info,
                        'content_bbox': content_bbox,
                        'confidence': 1.0,
                        'recognition_status': 'full_image'
                    })
            
            # 3. 智能裁剪
            print("✂️  步骤 3/3: 智能裁剪处理...")
            
            # 临时修改配置中的目标尺寸
            original_sizes = self.config.get('target_sizes', {})
            filtered_sizes = {k: v for k, v in original_sizes.items() if k in selected_sizes}
            self.config['target_sizes'] = filtered_sizes
            
            # 重新创建裁剪引擎
            self.cropping_engine = CroppingEngine(self.config)
            
            cropped_results = await self.cropping_engine.crop_images(content_regions)
            
            # 生成处理报告
            end_time = datetime.now()
            processing_time = (end_time - start_time).total_seconds()
            
            crop_stats = self.cropping_engine.get_crop_statistics(cropped_results)
            
            report = {
                'success': True,
                'total_files': len(files),
                'processed_files': len(cropped_results),
                'selected_sizes': selected_sizes,
                'ai_mode': ai_mode,
                'processing_time': processing_time,
                'crop_statistics': crop_stats,
                'results': cropped_results,
                'timestamp': end_time.isoformat()
            }
            
            self.logger.info(f"处理完成，共处理 {len(cropped_results)} 个文件，耗时 {processing_time:.2f} 秒")
            return report
            
        except Exception as e:
            self.logger.error(f"处理过程中发生错误: {str(e)}")
            return {
                'success': False,
                'error': str(e),
                'timestamp': datetime.now().isoformat()
            }
    
    def print_results(self, report: Dict[str, Any]):
        """打印处理结果"""
        print("\n" + "="*60)
        print("🎉 图片裁剪处理完成！")
        print("="*60)
        
        if report['success']:
            stats = report['crop_statistics']
            
            print(f"📊 处理统计:")
            print(f"   📁 总文件数: {report['total_files']}")
            print(f"   ✅ 成功处理: {stats['successful_files']}")
            print(f"   ❌ 失败文件: {stats['failed_files']}")
            print(f"   🖼️  总裁剪数: {stats['total_crops']}")
            print(f"   📈 平均每文件: {stats['average_crops_per_file']:.1f} 个裁剪")
            print(f"   ⏱️  处理时间: {report['processing_time']:.2f} 秒")
            
            print(f"\n📐 尺寸分布:")
            for size_name, count in stats['size_distribution'].items():
                print(f"   📏 {size_name}: {count} 个")
            
            print(f"\n🔧 处理配置:")
            mode_text = {
                'manga_split': '🎯 漫画分镜分割',
                'ai': '🧠 智能识别',
                'full': '🖼️  全图裁剪'
            }.get(report['ai_mode'], '未知模式')
            print(f"   🤖 处理模式: {mode_text}")
            print(f"   🎯 选择尺寸: {', '.join(report['selected_sizes'])}")
            
            # 如果是分镜分割模式，显示分镜统计
            if report['ai_mode'] == 'manga_split':
                total_panels = sum(len(r.get('panels', [])) for r in report.get('panel_results', []))
                print(f"   🎯 总分镜数: {total_panels}")
            
            print(f"\n📁 输出文件:")
            output_count = 0
            for result in report['results']:
                if result.get('cropping_status') == 'success':
                    for cropped_file in result.get('cropped_files', []):
                        output_count += 1
                        if output_count <= 10:  # 只显示前10个文件
                            print(f"   ✅ {cropped_file['filename']}")
                            print(f"      📏 尺寸: {cropped_file['width']}×{cropped_file['height']}")
                            print(f"      🔧 类型: {cropped_file['crop_type']}")
                            if cropped_file['crop_type'] == 'overlap':
                                print(f"      📊 序号: {cropped_file['crop_index']+1}/{cropped_file['total_crops']}")
                            print()
                else:
                    print(f"   ❌ {result.get('original_name', 'Unknown')} - {result.get('error', 'Unknown error')}")
            
            if stats['total_crops'] > 10:
                print(f"   ... 还有 {stats['total_crops'] - 10} 个文件")
            
            print(f"\n📂 输出目录: output/processed/")
            print(f"🎯 恭喜！所有图片已按指定尺寸智能裁剪完成！")
        else:
            print(f"❌ 处理失败: {report.get('error', 'Unknown error')}")
        
        print("="*60)

def show_banner():
    """显示程序横幅"""
    print("🚀 智能图片裁剪系统 v2.5")
    print("📷 基于AI视觉识别的智能图片裁剪工具")
    print("🎯 支持漫画分镜精确分割 + 智能裁剪 + 用户选择尺寸")
    print("="*60)

def main():
    """主函数"""
    show_banner()
    
    # 检查命令行参数
    if len(sys.argv) < 2:
        print("📋 使用方法:")
        print("   python crop.py <图片文件夹路径>")
        print()
        print("📝 示例:")
        print("   python crop.py ./test_images")
        print("   python crop.py /path/to/images")
        print()
        print("💡 提示：确保文件夹中包含图片文件（.jpg, .png, .bmp等）")
        sys.exit(1)
    
    input_folder = sys.argv[1]
    
    # 检查输入文件夹
    if not Path(input_folder).exists():
        print(f"❌ 错误：文件夹不存在 - {input_folder}")
        sys.exit(1)
    
    if not Path(input_folder).is_dir():
        print(f"❌ 错误：不是有效的文件夹 - {input_folder}")
        sys.exit(1)
    
    try:
        # 创建处理系统
        system = SmartImageCroppingSystem()
        
        # 获取用户选择
        selected_sizes = system.get_user_size_selection()
        ai_mode = system.get_ai_mode_selection()
        
        # 扫描图片文件
        print(f"\n📁 扫描文件夹: {input_folder}")
        image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp'}
        
        files = []
        for file_path in Path(input_folder).iterdir():
            if file_path.suffix.lower() in image_extensions:
                files.append({
                    'path': str(file_path),
                    'name': file_path.name,
                    'size': file_path.stat().st_size
                })
        
        if not files:
            print(f"❌ 在文件夹中未找到图片文件: {input_folder}")
            print("💡 支持的格式: .jpg, .jpeg, .png, .bmp, .tiff, .webp")
            sys.exit(1)
        
        print(f"✅ 找到 {len(files)} 个图片文件")
        
        # 处理图片
        print(f"\n🔄 开始处理图片...")
        result = asyncio.run(system.process_images(files, selected_sizes, ai_mode))
        
        # 显示结果
        system.print_results(result)
        
    except KeyboardInterrupt:
        print("\n\n👋 程序被用户中断")
        sys.exit(0)
    except Exception as e:
        print(f"\n❌ 程序执行错误: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()